const { DataTypes, Model, Deferrable, TINYINT } = require("sequelize");
const sequelize = require("../../sequelize");
const { Op } = require("sequelize");
const bcrypt = require("bcrypt");
const Role = require("../role/role");
const Rule = require("../rule/rule");
const RoleRule = require("../role/role_rule");
/**
 * 管理员模型
 */
class Manager extends Model {
    /**
     * 使用username获取limit个管理员
     * @param {string} username 
     * @param {number} limit 
     * @returns 
     */
    static async getManagerByUserName(username, limit) {
        return await this.findAll({
            where: {
                [Op.and]: [
                    {
                        username: username,
                    },
                    {
                        status: {
                            [Op.ne]: 0
                        },
                    }
                ],
            },
            limit: limit
        })
    }
    /**
     * 验证密码
     * @param {string} password 
     * @returns 是否验证成功
     */
    isPassword(password) {
        return bcrypt.compareSync(password, this.password)
    }
    /**
     * 使用username获取信息
     * @param {string} username 
     */
    static async getInfo(username) {
        let manager = await this.findOne({
            where: {
                username: username
            },
            include: [
                {
                    model: Role,
                    attributes: {
                        exclude: ["create_time", "update_time", "status"]
                    }
                }
            ],
            attributes: {
                exclude: ["password", "create_time", "update_time"]
            }
        })
        let json = manager.toJSON()
        let row = await Role.findOne({
            where: {
                id: json.Role.id,
            },
            include: {
                model: Rule,
                where: {
                    rule_id: 0,
                },
                attributes: {
                    exclude: ["create_time", "update_time"]
                }
            }
        })
        let rules = row.toJSON().Rules
        json["menus"] = []
        for (let i = 0; i < rules.length; i++) {
            await Rule.findAll({
                where: {
                    rule_id: rules[i].id
                }
            }).then(async value => {
                value.forEach(async value => {
                    let js = value.toJSON()
                    js["child"] = []
                    await Rule.getRules(js)
                    json.menus.push(js)
                })
            })

        }
        return json
    }
    /**
     * 使用username获取rule_id
     */
    static async getRule_ids(username) {
        return (await this.findOne({
            where: {
                username: username
            },
            include: [{
                model: Role,
                include: [
                    {
                        model: Rule,
                        attributes: ["id"],
                        through: {
                            attributes: []
                        }
                    }
                ],
                attributes: ["id"],
            }],
            attributes: []
        })).toJSON().Role.Rules
    }
    /**
     * 
     * @param {修改密码} password 
     * @returns 
     */
    async updatepassword(password) {
        return await this.set({ password: password }).save()
    }
    /**
     * 获取管理员列表
     * @param {*} limit 每页项数
     * @param {*} page 页码 
     * @returns 
     */
    static async getAll(limit, page) {
        return await this.findAll({
            order: ["id"],
            limit: limit,
            offset: limit * page - limit,
            attributes: {
                exclude: ["password"]
            },
            include: {
                model: Role,
                attributes: ["id", "name"]
            }
        })
    }
    async updateLastTime(date) {
        return await this.update({
            last_time: date
        })
    }
    static async delectById(id) {
        return await this.destroy(
            {
                where: {
                    id: id
                }
            }
        )
    }
    static async updateStatus(id, status) {
        if (status == 0 || status == 1) {
            return await this.update(
                { status, status },
                {
                    where: {
                        id: id
                    }
                }
            )
        }
        throw new Error("未知的状态号")
    }
    //检测是否有权限
    async isRule(rule_id) {
        let rules = await this.getRule()
    }
};
Manager.init({
    id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    status: {
        type: TINYINT,
        defaultValue: 1
    },
    username: {
        type: DataTypes.STRING,
        unique: true,
        allowNull: false
    },
    password: {
        type: DataTypes.STRING,
        set(password) {
            if (password == null || password == "" || password == undefined) {
                throw new Error("不允许空密码")
            }
            this.setDataValue("password", bcrypt.hashSync(password, 12))
        },
        allowNull: false
    },
    avatar: {
        type: DataTypes.STRING
    },
    role_id: {
        type: DataTypes.INTEGER,
        allowNull: false
    },
    super: {
        type: DataTypes.TINYINT,
        defaultValue: 0,
        set(value) {
            throw new Error("不允许设置超管标识")
        }
    },
    //上次登录时间
    last_time: {
        type: DataTypes.DATE
    }
}, {
    sequelize,
    modelName: "Manager",
    tableName: "manager",
    createdAt: "create_time",
    updatedAt: "update_time",
})
module.exports = Manager